<template lang="pug">
mt-dialog(
  v-model="appmodel"
  cancel-text="取消"
  title="批次列表"
  :on-close="closeModel"
  :on-cancel="closeModel"
  hide-confirm
  size="large"
)
  data-page(
      v-bind="pageParams"
      ref="pageRef"
      )
    .container
      .container_left
        span(style="color: rgb(53, 160, 0);") 送检批次号 {{ batchNumber }}
      .container_right
        mt-button(
        v-for="item of buttonTopList" 
        :key="item.type"
        v-bind="item"
        )
    mt-table(
      v-bind="tableProps"
    )
  rejection(v-model="rejectionShow" :selectionRow="actualSpecimen" @message-to-parent="getData")
  sampleTrajectory(v-model="trajectoryShow" :selectionRow="specimenRow")
</template>

<script setup lang="ts">
import {
  type FormItemProps,
  type IAction,
  type DataPageProps,
  type TableProps,
  useNotify,
  DataPage,
  Table,
} from "@scmt/common-components";
import { type ApiBasedOptions, useApi } from "@scmt/core-api";
import {
  type SpecimenEntity,
  type SpecimenQueryParams,
} from "@scmt/api-lis-specimen";
import rejection from "./rejection.vue";
import sampleTrajectory from "../../components/sampleTrajectory.vue";
import { useUtils } from "@scmt/lib-utils";
import { type PatientEntity } from "@scmt/api-patient";
import {
  ESpecimenStatus,
  ESpeimenTableColumnKey,
  specimenColumns,
} from "@scmt/api-common";
import { useRequest } from "@scmt/common-hooks";
import { useGroup } from "../../composable/group";

const $api = useApi();
const $notify = useNotify();
const $utils = useUtils();
const queryPramas = reactive<SpecimenQueryParams>({
  startDate: $utils.date().startOf("date").format("YYYY-MM-DD HH:mm:ss"),
  endDate: $utils.date().endOf("date").format("YYYY-MM-DD HH:mm:ss"),
  pageNum: 1,
  pageSize: 20,
});

//添加 Props属性
const props = defineProps({
  batchNumber: {
    type: String,
    default: "",
  },
});
const appmodel = defineModel({
  default: false,
});
const emit = defineEmits(["message-to-parent"]);

const rejectionShow = ref(false);
const trajectoryShow = ref(false);
const specimenRow = ref({});
const pageRef = ref<null | InstanceType<typeof DataPage>>(null);
const selectionRow = ref<SpecimenEntity[]>([]);
const patients = ref<ApiBasedOptions<PatientEntity>>([]);
const tableRef = ref<null | InstanceType<typeof Table>>(null);

const { request, data, loadingMap } = useRequest(
  {
    tableData: (q: any) => {
      const params = Object.assign({}, queryPramas, q);
      return $api.lis.specimen.getSpecimenPageList(params);
    },
    batchGenerateBarcode: (q: any) => {
      return $api.lis.specimen.batchGenerateBarcode(q).then(() => {
        $notify.success("取消签收成功");
        getData();
      });
    },
    batchSampleSigning: (q: any) => {
      return $api.lis.specimen
        .batchSampleSigning(q.specimenList, q.batchNumber)
        .then(() => {
          $notify.success("签收成功");
          emit("message-to-parent");
          appmodel.value = false;
        });
    },
    printBarcode: (val: string[]) => {
      return $api.lis.specimen.printBarcode(val).then(() => {});
    },
    patients: async (keyword: string) => {
      if (!keyword && patients.value.length) {
        return patients.value;
      }

      return $api.patient.listAsOptions({ keyword });
    },
  },
  {
    tableData: {
      items: [] as SpecimenEntity[],
      pagination: {
        total: 0,
        pageNum: queryPramas.pageNum,
        pageSize: queryPramas.pageSize,
      },
    },
  }
);

const { batchNumber } = toRefs(props);
const { tableData } = toRefs(data);
const { getCellClassName, getGroupKey, spanMethod } = useGroup(tableData);

const actualSpecimen = computed(() => {
  const selectKeys = Array.from(
    new Set(selectionRow.value.map((item) => item[getGroupKey(item)]))
  );

  return tableData.value.items.filter((i) =>
    selectKeys.includes(i[getGroupKey(i)])
  );
});

const buttonTopList = computed(() => {
  const noSelect = selectionRow.value.length === 0;

  return [
    {
      label: "签收",
      type: "primary",
      visible: tableData.value.items.some(
        (i) => i.state === ESpecimenStatus.Submission
      ),
      disabled:
        noSelect ||
        actualSpecimen.value.some(
          (i) => i.state !== ESpecimenStatus.Submission
        ),
      loading: loadingMap.batchSampleSigning,
      onClick: () => {
        request("batchSampleSigning", {
          specimenList: actualSpecimen.value,
          batchNumber: batchNumber.value,
        });
      },
    },
    {
      label: "取消签收",
      type: "primary",
      visible: tableData.value.items.some(
        (i) => i.state === ESpecimenStatus.Receipt
      ),
      disabled:
        noSelect ||
        actualSpecimen.value.some((i) => i.state !== ESpecimenStatus.Receipt),
      loading: loadingMap.batchGenerateBarcode,
      onClick: () => {
        request("batchGenerateBarcode", {
          specimenList: actualSpecimen.value.map((item) => item.id),
          status: ESpecimenStatus.Submission,
        });
      },
    },
    {
      label: "拒收",
      type: "primary",
      visible: tableData.value.items.some(
        (i) => i.state === ESpecimenStatus.Submission
      ),
      disabled:
        noSelect ||
        actualSpecimen.value.some(
          (i) => i.state !== ESpecimenStatus.Submission
        ),
      onClick: () => {
        rejectionShow.value = true;
      },
    },
  ].filter((i) => i.visible === void 0 || i.visible);
});

const pageParams = computed<DataPageProps>(() => {
  const queryFields: FormItemProps[] = [
    {
      prop: "outpatientNumber",
      label: "业务编号",
    },
    {
      prop: "patientName",
      label: "患者姓名",
    },
    {
      prop: "barcode",
      label: "标本条码",
    },
    {
      prop: "billingDepartment",
      label: "开单科室",
      as: "select",
      options: {
        render: "office-table",
        loadMethod: $api.upms.org.listAsOptions,
      },
    },
    {
      prop: "billingTime",
      label: "开单时间",
      as: "date",
    },
  ];

  const dataPageProps: DataPageProps = {
    loading: loadingMap.tableData,
    queryModel: queryPramas,
    queryFields,
    onQuery: getData,
    onAct: onPageActions,
    columns: 4,
    flex: true,
  };

  return dataPageProps;
});

const tableColumns = computed<TableProps["columns"]>(() => [
  {
    prop: "_selection",
    type: "selection",
    width: "60px",
  },
  specimenColumns[ESpeimenTableColumnKey.Source],
  specimenColumns[ESpeimenTableColumnKey.OutpatientNumber],
  specimenColumns[ESpeimenTableColumnKey.PatientName],
  specimenColumns[ESpeimenTableColumnKey.Sex],
  specimenColumns[ESpeimenTableColumnKey.Age],
  specimenColumns[ESpeimenTableColumnKey.ApplicationProject],
  specimenColumns[ESpeimenTableColumnKey.SpecimenTypeId],
  specimenColumns[ESpeimenTableColumnKey.Barcode],
  specimenColumns[ESpeimenTableColumnKey.State],
  specimenColumns[ESpeimenTableColumnKey.BillingDepartment],
  specimenColumns[ESpeimenTableColumnKey.BillingDoctor],
  specimenColumns[ESpeimenTableColumnKey.BillingTime],
  {
    prop: "sampleContainer",
    tooltip: true,
    label: "试管名称",
    width: "90px",
    render: ({ row }) => {
      let resText = row.sampleContainer + "";
      return h(
        "div",
        {
          style: {
            width: "100%",
            background: row.sampleContainerColor,
          },
        },
        resText
      );
    },
  },
  {
    prop: "specs",
    tooltip: true,
    label: "规格",
    minWidth: 120,
  },
  {
    prop: "additive",
    label: "添加剂",
    tooltip: true,
  },
  {
    prop: "collectionMethodName",
    label: "采集方式",
    minWidth: 100,
  },
  {
    prop: "bloodCollectionVolume",
    label: "采血量",
    tooltip: true,
  },
  {
    prop: "collectionName",
    label: "采集医生",
  },
  {
    prop: "collectionTime",
    label: "采集时间",
    format: "datetime",
  },
  {
    prop: "sendInspectionName",
    label: "送检医生",
  },
  {
    prop: "sendInspectionTime",
    label: "送检时间",
    format: "datetime",
  },
  {
    prop: "signeeName",
    label: "签收人",
  },
  specimenColumns[ESpeimenTableColumnKey.Urgent],
  {
    prop: "_operation",
    label: "操作",
    fixed: "right",
    actions: [
      {
        label: "标本轨迹",
        event: "check",
        type: "primary",
      },
    ],
  },
]);

const tableProps = computed(() => {
  const { tableData } = toRefs(data);

  const tableProps: TableProps = {
    loading: loadingMap.tableData,
    data: tableData.value?.items,
    pagination: tableData.value?.pagination,
    insertIndex: false,
    columns: tableColumns.value,
    onAct: onPageActions,
    onPaginate: getData,
    onSelectionChange: (selection: any) => {
      selectionRow.value = selection;
    },
    highlightCurrentRow: true,
    cellClassName: getCellClassName,
    spanMethod,
    ref: tableRef,
  };
  return tableProps;
});

watch(appmodel, (visible: boolean) => {
  if (visible) {
    if (batchNumber.value) {
      getData();
    }
  }
});

const onPageActions = (action: IAction, model?: any) => {
  switch (action.event) {
    case "rejection":
      rejectionShow.value = true;
      break;
    case "check":
      specimenRow.value = model;
      trajectoryShow.value = true;
      break;
  }
};

const closeModel = () => {
  appmodel.value = false;
};

const getData = (q?: any) => {
  request("tableData", {
    params: Object.assign({}, q, {
      batchNumber: batchNumber.value,
    }),
    onSuccess: (res) => {
      nextTick(() => {
        const couldReciveItems = res.items.filter(
          (i) => i.state === ESpecimenStatus.Submission
        );

        if (couldReciveItems.length > 0) {
          couldReciveItems.forEach((i) => {
            tableRef.value?.toggleRowSelection(i, true);
          });
        }
      });
    },
  });
};
</script>

<style lang="less" scoped>
.container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--mt-margin);
  &__left {
  }
  &__right {
    justify-content: right;
  }
}

@text-size: calc(var(--unit) * 20);
:deep(.el-table) {
  &__body {
    .group-text {
      position: relative;

      &::before {
        position: absolute;
        display: inline-block;
        color: var(--el-color-primary);
        font-size: var(--mt-fs-mini);
        top: 50%;
        transform: translate(-50%, -50%);
        content: "合";
        font-weight: 700;
        width: @text-size;
        height: @text-size;
        text-align: center;
        line-height: @text-size;
        border-radius: 50%;
        background-color: var(--el-color-white);
        z-index: 1;
      }
    }

    .group-text--offset {
      position: relative;
      &::before {
        top: -50%;
        transform: translate(-50%, 50%);
      }
    }
  }
}
</style>
